public class DNodeStack<E> implements IStack<E> {
	
	protected DNode<E> top; // reference to the head node
	protected int size; // number of elements in the stack
	
	public DNodeStack() { // constructs an empty stack
		top = null;
		size = 0;
	}
	
	public int size(){
		return size;
	}
	
	public boolean isEmpty() {
		return top == null;
	}
	
	public void push(E elem) {
		DNode<E> v = new DNode<E>(elem, top); // create and link-in a new node
		top = v;
		size++;
	}
	
	public E top() throws EmptyStackException {
		if (isEmpty())
			throw new EmptyStackException("Stack is empty.");
		
		return top.getElement();
	}
	
	public E pop() throws EmptyStackException {
		if (isEmpty())
			throw new EmptyStackException("Stack is empty.");
		
		E temp = top.getElement();
		top = top.getNext(); // link-out the former top node
		size--;
		return temp;
	}
	
	public IStack<Object> copyToStack(IStack<Object> dest){
		
		DNode<E> node = top;
		while (node!=null) // while there is a new node, we continue
		{
			dest.push(node.getElement());
			node=node.getNext();
		}
		return dest;
	}
	
	@Override
	public String toString() {		
		String str="";
		DNode<E> node = top;
		while (node!=null) // while there is a new node, we continue
		{
			str += node.getElement().toString()+"\n"; // for each node we use the toString method of his element to describe the node
			node=node.getNext();
		}
		return str;
	}
}